package edu.bbu.bs.backend.repository.beans;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import edu.bbu.bs.backend.model.AbstractModel;
import edu.bbu.bs.backend.repository.BaseRepository;
import edu.bbu.bs.backend.repository.exceptions.RepositoryException;

public class BaseRepositoryBean<T extends AbstractModel, I> implements BaseRepository<T, I> {

	private final Class<T> clazz;

	@PersistenceContext(unitName = "biblio")
	private EntityManager entityManager;

	public BaseRepositoryBean(final Class<T> clazz) {
		this.clazz = clazz;
	}

	@Override
	public List<T> getAll() throws RepositoryException {
		try {
			Query query = entityManager.createQuery("SELECT a FROM Author a");
			return query.getResultList();
		} catch (IllegalArgumentException | PersistenceException e) {
			throw new RepositoryException("Error in method getById.", e);
		}
	}

	@Override
	public T getById(I id) throws RepositoryException {
		try {
			return entityManager.find(clazz, id);
		} catch (IllegalArgumentException | PersistenceException e) {
			throw new RepositoryException("Error in method getById.", e);
		}
	}

	@Override
	public T save(T item) throws RepositoryException {
		try {
			entityManager.persist(item);
			entityManager.flush();
			return item;
		} catch (IllegalArgumentException | PersistenceException e) {
			throw new RepositoryException("Error in save method.", e);
		}
	}

	@Override
	public T merge(T item) throws RepositoryException {
		try {
			return entityManager.merge(item);
		} catch (IllegalArgumentException | PersistenceException e) {
			throw new RepositoryException("Error in merge method.", e);
		}
	}

	@Override
	public void delete(T item) throws RepositoryException {
		try {
			T managedItem = entityManager.merge(item);
			entityManager.remove(managedItem);
		} catch (IllegalArgumentException | PersistenceException e) {
			throw new RepositoryException("Error in delete method.", e);
		}
	}

}
